#ifndef OCK_MEMORY_BRIDGE_OCK_HMM_ALLOCATOR_H
#define OCK_MEMORY_BRIDGE_OCK_HMM_ALLOCATOR_H
#include <memory>
#include <vector>
#include "ock/hmm/mgr/OckHmmMemoryPool.h"

namespace ock{
namespace hmm {
namespace helper {
template <typename _Tp>
class OckHmmAllocator
{
public:
    typedef _Tp value_type;
public:
    OckHmmAllocator(OckHmmMemoryPool &hmmPool) : hmmPool(hmmPool)
    {};
    _Tp *allocate(size_t nCount)
    {
        return reinterpret_cast<_Tp *>(hmmPool.AllocateHost(nCount * sizeof(_Tp)));
    }
    void deallocate(_Tp *addr, size_t nCount)
    {
        hmmPool.DeallocateHost(reinterpret_cast<uint8_t *>(addr), nCount * sizeof(_Tp));
    }
    ~OckHmmAllocator();
private:
    OckHmmMemoryPool &hmmPool;
};

using OckHmmUint8Allocater = hmm::helper::OckHmmAllocator<uint8_t>;
using OckHmmUint16Allocater = hmm::helper::OckHmmAllocator<uint16_t>;
using OckHmmUint32Allocater = hmm::helper::OckHmmAllocator<uint32_t>;
using OckHmmUint64Allocater = hmm::helper::OckHmmAllocator<uint64_t>;

using OckHmmUint8Vector = std::vector<uint8_t, OckHmmUint8Allocater>;
using OckHmmUint16Vector = std::vector<uint16_t, OckHmmUint16Allocater>;
using OckHmmUint32Vector = std::vector<uint32_t, OckHmmUint32Allocater>;
using OckHmmUint64Vector = std::vector<uint64_t, OckHmmUint64Allocater>;

using OckHmmInt8Allocater = hmm::helper::OckHmmAllocator<int8_t>;
using OckHmmInt16Allocater = hmm::helper::OckHmmAllocator<int16_t>;
using OckHmmInt32Allocater = hmm::helper::OckHmmAllocator<int32_t>;
using OckHmmInt64Allocater = hmm::helper::OckHmmAllocator<int64_t>;

using OckHmmInt8Vector = std::vector<int8_t, OckHmmInt8Allocater>;
using OckHmmInt16Vector = std::vector<int16_t, OckHmmInt16Allocater>;
using OckHmmInt32Vector = std::vector<int32_t, OckHmmInt32Allocater>;
using OckHmmInt64Vector = std::vector<int64_t, OckHmmInt64Allocater>;

}
}
}

#endif